package com.web.exiaodao.remote.service.impl;

import com.alibaba.fastjson.JSON;
import com.web.exiaodao.business.constant.JConstant;
import com.web.exiaodao.business.entity.ShopCar;
import com.web.exiaodao.business.repository.ShopCarRepository;
import com.web.exiaodao.remote.service.ApiShopCarService;
import com.web.exiaodao.remote.service.ApiShopStandardNameService;
import com.web.exiaodao.remote.vo.ShopCarVo;
import com.web.exiaodao.remote.vo.ShopStandardVo;
import com.web.exiaodao.remote.vo.ShopVo;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.service.impl.BaseService;
import com.web.webstart.base.util.SqlResultUtil;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.MyPage;
import com.web.webstart.base.util.result.XaResult;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.*;

/**
 * @author: zhangl
 * @times: 2016-11-02 18:25:27
 * 类的说明：前端APIShopCar接口实现类
 **/
@Service("ApiShopCarService")
@Transactional(readOnly = false)
public class ApiShopCarServiceImpl extends BaseService<ShopCar> implements ApiShopCarService {

    private static final Logger LOGGER = Logger.getLogger(ApiShopCarServiceImpl.class);

    @Autowired
    ShopCarRepository shopCarRepository;
    @Autowired
    ApiShopStandardNameService shopStandardNameService;

    @Override
    public XaResult<Page<ShopCarVo>> findMyCar(Long userId, Integer begin, Integer count)
            throws BusinessException {
        XaResult<Page<ShopCarVo>> xr = new XaResult<>();
        List<Object> params = new ArrayList<>();    //参数集合
        StringBuffer sql = new StringBuffer();    //列表查询语句
        StringBuffer countSql = new StringBuffer();    //数据统计语句
        StringBuffer standardsSql = new StringBuffer();    //规格查询语句
        sql.append(
                "SELECT car.id as shopcarId, shop.id as shopProductId, car.car_number, car.user_id, car.standard_ids,shop.shop_product_name, shop.shop_product_price, shop.original_price, shop.shop_product_pic_urls, shop.status , shop.discount_rate " +
                        "FROM tb_xa_shopcar car " +
                        "LEFT JOIN tb_xa_shop shop ON car.shop_id = shop.id " +
                        "WHERE car.user_id = ? AND 1 = 1  AND shop.status = ?  " +
                        "ORDER BY car.create_time ASC "
        );
        countSql.append(" select count(*) FROM tb_xa_shopcar c LEFT JOIN  tb_xa_shop s on c.id = s.id WHERE c.user_id = ? AND 1 = 1 AND s.status = ?  ");
        params.add(userId);    //添加查询条件
        params.add(XaConstant.Status.publish);
        //查询的列表集合
        List<Object[]> objs = this.queryParams(sql.toString(), begin * count, count, params);
        //查询的总条数
        List<Object[]> c = this.queryParams(countSql.toString(), null, null, params);
        //SELECT valueId, shop_id, nameId, shop_stands_name, shop_stands_value FROM view_shop_standards  WHERE valueId in (13,14,15,16)
        Set<String> params_set = new HashSet<>();
        for (Object[] obj : objs) {
            String str = (String) obj[4];
            if (XaUtil.isNotEmpty(str)) {
                params_set.addAll(Arrays.asList(str.split(JConstant.SYMBOL_DOT)));
            }
        }
        //查询所有的规格
        List<ShopStandardVo> shopStandardVos = new ArrayList<>();
        XaResult<List<ShopStandardVo>> shopStands = shopStandardNameService.findShopStandsByValueIds(params_set);
        if (shopStands != null && XaUtil.isNotEmpty(shopStands.getObject()) && shopStands.getObject() instanceof List) {
            shopStandardVos.addAll(shopStands.getObject());
        }
        //数据结果集
        List<ShopCarVo> cars = new ArrayList<ShopCarVo>();
        for (Object[] obj : objs) {
            //购物车信息
            ShopCarVo vo = new ShopCarVo();
            vo.setId(obj[0] == null ? null : ((BigInteger) obj[0]).longValue());
            vo.setShopId(obj[1] == null ? null : ((BigInteger) obj[1]).longValue());
            vo.setCarNumber(obj[2] == null ? null : ((BigInteger) obj[2]).longValue());
            vo.setUserId(obj[3] == null ? null : ((BigInteger) obj[3]).longValue());
            vo.setStandardIds(obj[4] == null ? null : (String) obj[4]);
            //商品信息
            ShopVo shop = new ShopVo();
            shop.setShopProductName((String) obj[5]);
            shop.setShopProductPrice((String) obj[6]);
            shop.setOriginalPrice((String) obj[7]);
            shop.setShopProductPicUrls((String) obj[8]);
            shop.setStatus(SqlResultUtil.getSqlResultInteger(obj[9]));
            shop.setDiscountRate(SqlResultUtil.getSqlResultDouble(obj[10]));
            //购物车选择的规格
            Set<ShopStandardVo> standardSet = new HashSet<>();
            for (int j = 0; j < shopStandardVos.size(); ++j) {
                List standidsList = Arrays.asList(vo.getStandardIds().split(JConstant.SYMBOL_DOT));
                String valueid = shopStandardVos.get(j).getValueId().toString();
                if (standidsList.contains(valueid)) {
                    standardSet.add(shopStandardVos.get(j));
                }
            }
            vo.setSelectStandard(standardSet);
            vo.setShop(shop);
            cars.add(vo);
        }
        Page<ShopCarVo> page = new MyPage<ShopCarVo>(begin, count, cars, Integer.valueOf(c.get(0) + ""));
        xr.setObject(page);
        return xr;
    }

    @Override
    public XaResult<Long> findMyCarCount(Long userId) throws BusinessException {
        XaResult<Long> xr = new XaResult<>();
        long cout = shopCarRepository.findByUserId(userId);
        xr.setObject(cout);
        return xr;
    }

    @Override
    public XaResult<ShopCarVo> addCar(ShopCar shopCar)
            throws BusinessException {
        XaResult<ShopCarVo> xr = new XaResult<ShopCarVo>();
        ShopCar obj = shopCarRepository.findByShopIdAndStandardIdsAndUserIdAndStatusNot
                (shopCar.getShopId(), shopCar.getStandardIds(), shopCar.getUserId(), XaConstant.Status.delete);
        if (XaUtil.isNotEmpty(obj)) {
            obj.setCarNumber(obj.getCarNumber() + shopCar.getCarNumber());
            obj.setId(obj.getId());
            obj = shopCarRepository.save(obj);
        } else {
            obj = shopCarRepository.save(shopCar);
        }
        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), ShopCarVo.class));
        xr.getObject().setId(obj.getId());
        return xr;
    }

    @Override
    public XaResult<List<ShopCarVo>> modifyCar(String shopCar)
            throws BusinessException {
        XaResult<List<ShopCarVo>> xr = new XaResult<List<ShopCarVo>>();
        List<ShopCarVo> cars = null;
        try {
            //把字符串转化为购物车集合
            cars = JSON.parseArray(shopCar, ShopCarVo.class);
            if (XaUtil.isNotEmpty(cars)) {
                //循环集合修改数量
                for (ShopCarVo vo : cars) {
                    if (XaUtil.isEmpty(vo.getId()) || XaUtil.isEmpty(vo.getCarNumber())
                            || vo.getId() < 0 || vo.getCarNumber() < 0) {
                        xr.error("商品id获取购物车商品数量不能不正确", true);
                        return xr;
                    }
                    List<Object> params = new ArrayList<Object>();
                    String sql = "UPDATE tb_xa_shopcar SET car_number = ? WHERE id = ?";
                    params.add(vo.getCarNumber());
                    params.add(vo.getId());
                    this.update(sql, params);
                }
                xr.setObject(cars);
            }
        } catch (Exception e) {
            xr.error("json格式错误");
            return xr;
        }
        return xr;
    }

    @Override
    public XaResult<ShopCarVo> deleteCar(String ids, Long userId)
            throws BusinessException {
        XaResult<ShopCarVo> xr = new XaResult<ShopCarVo>();
        String sql = "delete from tb_xa_shopcar where user_id=? and id in (";
        String[] modelId = ids.replaceAll("，", ",").split(",");
        for (String l : modelId) {
            sql += l;
            if ((modelId[modelId.length - 1]) != l) {
                sql += ",";
            }
        }
        sql += ")";
        List<Object> params = new ArrayList<Object>();
        params.add(userId);
        this.update(sql, params);
        return xr;
    }

    /**
     * 删除购物车里面无效的商品
     * <p>
     * CREATE PROCEDURE `pro_delShopCar_InvalidShop`() COMMENT '清除购物车里面的无效商品'
     * BEGIN
     * DECLARE  no_more_record INT DEFAULT 0;
     * -- 定义变量
     * DECLARE shopCarId   INTEGER;
     * -- 定义游标
     * <p>
     * # 清除购物车里面的无效商品  临时表
     * # 1:ok 查询
     * # DELETE  FROM tb_xa_order_detail WHERE order_no IN (SELECT group_concat(order_no)  FROM tb_xa_order WHERE order_type = 52);
     * # 2：失败查询  原因是在更新这个表和数据时又查询了它，而查询的数据又做了更新的条件  http://blog.csdn.net/yaerfeng/article/details/7876461
     * # DELETE  FROM tb_xa_shopcar WHERE id IN (
     * #   (SELECT group_concat(car.id) FROM tb_xa_shopcar car LEFT JOIN tb_xa_shop shop ON car.shop_id = shop.id WHERE shop.status <> 2)
     * # )
     * <p>
     * <p>
     * # 临时表  http://www.nowamagic.net/librarys/veda/detail/1317
     * # CREATE TEMPORARY TABLE tmp_table_shopcar (
     * #   carId BIGINT NOT NULL,
     * #   shopId BIGINT NOT NULL,
     * #   shopStatus INT NOT NULL
     * # );
     * <p>
     * # 创建临时表，并导入数据
     * CREATE TEMPORARY TABLE tmp_table_shopcar (SELECT car.id as carId, shop.id as shopId, shop.status as shopStatus FROM tb_xa_shopcar car LEFT JOIN tb_xa_shop shop ON car.shop_id = shop.id WHERE shop.status <> 2);
     * <p>
     * DECLARE cur CURSOR FOR  SELECT carId FROM tmp_table_shopcar;
     * -- 如果没有记录游标设置为1
     * DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET  no_more_record = 1;
     * -- 打开游标
     * OPEN cur;
     * -- 将第一条记录赋值给变量
     * FETCH cur INTO shopCarId ;
     * -- 循环游标
     * WHILE no_more_record != 1 DO
     * DELETE FROM tb_xa_shopcar WHERE id IN (shopCarId);
     * -- 将下一条记录赋值给变量
     * FETCH cur INTO shopCarId;
     * END WHILE;关闭游标exiaodao
     * --
     * CLOSE cur;
     * END
     */
    @Override
    public void deleteInvalidCar() throws BusinessException {
        //查询所有的无效的购物车id
        String sql = "SELECT group_concat(car.id) FROM tb_xa_shopcar car LEFT JOIN tb_xa_shop shop ON car.shop_id = shop.id WHERE shop.status <> 2";
        List allIds = this.query(sql, 0, 1);
        if (XaUtil.isNotEmpty(allIds) && allIds.size() > 0) {
            //删除
            String ids = allIds.get(0) + "";
            String delSql = "DELETE FROM tb_xa_shopcar WHERE id IN ( " + ids + " );";
            int affectRows = this.update(delSql);
            LOGGER.info("购物车清楚无效商品条数：" + affectRows);
        }
    }
}
